<!DOCTYPE html>
<title>CSS Anchor Positioning: position-area in @position-try</title>
<link rel="help" href='https://drafts.csswg.org/css-anchor-position-1/#position-try-fallbacks'>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<style>
  #cb {
    position: relative;
    width: 200px;
    height: 200px;
    border: 1px solid black;
  }
  #anchor {
    position: absolute;
    left: 100px;
    top: 100px;
    width: 50px;
    height: 50px;
    background-color: tomato;
    anchor-name: --a;
  }
  #target {
    left: 200px; /* force fallback */
  }
  #target, #ref {
    position: absolute;
    width: 40px;
    height: 40px;
    background-color: skyblue;
    position-area: bottom right;
    position-anchor: --a;
  }
  #ref {
    background-color: seagreen;
  }
</style>
<style id=style>
</style>
<div id=cb>
  <div id=anchor></div>
  <div id=target></div>
  <div id=ref></div>
</div>
<script>

// Test that inside-area, when used inside @position-try, works the same
// as when it's specified in the base style.
function test_position_area_ref(position_area) {
  test((t) => {
    t.add_cleanup(() => {
      style.textContent = '';
    });
    style.textContent = `
      @position-try --pt {
        inset: unset; /* Undo force fallback */
        position-area: ${position_area};
      }
      #target {
        position-try-fallbacks: --pt;
      }
      #ref {
        position-area: ${position_area};
      }
    `;
    assert_true(CSS.supports('position-area', 'top left'));
    assert_true(CSS.supports('position-try-fallbacks', '--x'));
    assert_equals(target.offsetLeft, ref.offsetLeft, 'offsetLeft');
    assert_equals(target.offsetTop, ref.offsetTop, 'offsetTop');
  }, `${position_area}`);
}

test_position_area_ref('none');
test_position_area_ref('span-all');
test_position_area_ref('span-all span-all');
test_position_area_ref('top left');
test_position_area_ref('top center');
test_position_area_ref('top right');
test_position_area_ref('center left');
test_position_area_ref('center center');
test_position_area_ref('center right');
test_position_area_ref('bottom left');
test_position_area_ref('bottom center');
test_position_area_ref('bottom right');
test_position_area_ref('start start');
test_position_area_ref('start center');
test_position_area_ref('start end');
test_position_area_ref('center start');
test_position_area_ref('center end');
test_position_area_ref('end start');
test_position_area_ref('end center');
test_position_area_ref('end end');
test_position_area_ref('self-start self-start');
test_position_area_ref('self-start center');
test_position_area_ref('self-start self-end');
test_position_area_ref('center self-start');
test_position_area_ref('center self-end');
test_position_area_ref('self-end self-start');
test_position_area_ref('self-end center');
test_position_area_ref('self-end self-end');
test_position_area_ref('y-start x-start');
test_position_area_ref('y-start center');
test_position_area_ref('y-start x-end');
test_position_area_ref('center x-start');
test_position_area_ref('center x-end');
test_position_area_ref('y-end x-start');
test_position_area_ref('y-end center');
test_position_area_ref('y-end x-end');
test_position_area_ref('y-self-start x-self-start');
test_position_area_ref('y-self-start center');
test_position_area_ref('y-self-start x-self-end');
test_position_area_ref('center x-self-start');
test_position_area_ref('center x-self-end');
test_position_area_ref('y-self-end x-self-start');
test_position_area_ref('y-self-end center');
test_position_area_ref('y-self-end x-self-end');
test_position_area_ref('span-y-self-start span-x-self-end');
test_position_area_ref('span-bottom span-all');

</script>

<style>
  @position-try --top {
    inset: unset; /* Undo force fallback */
    position-area: top;
  }
  @position-try --right {
    inset: unset; /* Undo force fallback */
    position-area: right;
  }
  @position-try --bottom {
    inset: unset; /* Undo force fallback */
    position-area: bottom;
  }
  @position-try --left {
    inset: unset; /* Undo force fallback */
    position-area: left;
  }
</style>
<script>

// Test that an element with the specified position-try-fallbacks is placed
// at the same position as a reference element with position-area:`expected`.
// This test uses #target/#ref size of 60x60px, which causes overflow if
// if we attempt the --right and --bottom positions.
function test_position_area_placement(position_try_fallbacks, expected) {
  test((t) => {
    style.textContent = `
      #target, #ref {
        width: 60px;
        height: 60px;
      }
      #target {
        position-try-fallbacks: ${position_try_fallbacks};
      }
      #ref {
        position-area: ${expected};
      }
    `;
    assert_true(CSS.supports('position-area', 'top left'));
    assert_true(CSS.supports('position-try-fallbacks', '--x'));
    assert_equals(target.offsetLeft, ref.offsetLeft, 'offsetLeft');
    assert_equals(target.offsetTop, ref.offsetTop, 'offsetTop');
  }, `Placement: ${position_try_fallbacks}`);
}

test_position_area_placement('--top', 'top');
test_position_area_placement('--left', 'left');

// No space to to the right/bottom:
test_position_area_placement('--right, --top', 'top');
test_position_area_placement('--bottom, --top', 'top');
test_position_area_placement('--bottom, --right, --top', 'top');
test_position_area_placement('--bottom, --right, --left, --top', 'left');
test_position_area_placement('--bottom, --left, --top, --right', 'left');

// Flipping:
test_position_area_placement('--right flip-inline', 'left');
test_position_area_placement('--bottom flip-block', 'top');
test_position_area_placement('--left flip-start', 'top');

// left + flip-inline => right (no space).
test_position_area_placement('--left flip-inline, --top', 'top');
// top + flip-block => bottom (no space).
test_position_area_placement('--top flip-block, --left', 'left');
// left + flip-start flip-block => bottom (no space).
test_position_area_placement('--left flip-start flip-block, --left', 'left');

</script>
